package com.ls.server.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ls.server.domain.ChatModel;
import com.ls.server.domain.ChatSession;
import com.ls.server.dto.ChatQueryDTO;
import com.ls.server.dto.ChatSessionDTO;
import com.ls.server.mapper.ChatModelMapper;
import com.ls.server.mapper.ChatSessionMapper;
import com.ls.server.service.ChatSessionService;
import com.ls.server.vo.ChatSessionVO;
import com.ls.server.vo.PageResult;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import java.util.stream.Collectors;

/**
 * 聊天会话Service实现类
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class ChatSessionServiceImpl extends ServiceImpl<ChatSessionMapper, ChatSession> implements ChatSessionService {

    private final ChatModelMapper modelMapper;

    @Override
    public PageResult<ChatSessionVO> page(ChatQueryDTO queryDTO) {
        Page<ChatSession> page = new Page<>(queryDTO.getPageNum(), queryDTO.getPageSize());
        LambdaQueryWrapper<ChatSession> wrapper = new LambdaQueryWrapper<>();
        
        // 添加查询条件
        if (queryDTO.getUserId() != null) {
            wrapper.eq(ChatSession::getUserId, queryDTO.getUserId());
        }
        
        if (StringUtils.hasText(queryDTO.getKeyword())) {
            wrapper.like(ChatSession::getTitle, queryDTO.getKeyword())
                  .or()
                  .like(ChatSession::getLastMessage, queryDTO.getKeyword());
        }
        
        // 排序
        wrapper.orderByDesc(ChatSession::getUpdateTime);
        
        IPage<ChatSession> result = baseMapper.selectPage(page, wrapper);
        List<ChatSessionVO> voList = convertToVoList(result.getRecords());
        
        return new PageResult<>(voList, result.getTotal());
    }

    @Override
    public List<ChatSessionVO> listUserSessions(Long userId) {
        LambdaQueryWrapper<ChatSession> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(ChatSession::getUserId, userId)
               .orderByDesc(ChatSession::getUpdateTime);
        
        List<ChatSession> sessions = baseMapper.selectList(wrapper);
        return convertToVoList(sessions);
    }

    @Override
    public ChatSessionVO getSessionById(String sessionId) {
        LambdaQueryWrapper<ChatSession> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(ChatSession::getSessionId, sessionId);
        
        ChatSession session = baseMapper.selectOne(wrapper);
        if (session == null) {
            return null;
        }
        return convertToVo(session);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public String createSession(ChatSessionDTO dto) {
        String sessionId = UUID.randomUUID().toString().replace("-", "");
        
        ChatSession session = new ChatSession();
        BeanUtils.copyProperties(dto, session);
        session.setSessionId(sessionId);
        session.setCreateTime(LocalDateTime.now());
        session.setUpdateTime(LocalDateTime.now());
        
        baseMapper.insert(session);
        return sessionId;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateSession(ChatSessionDTO dto) {
        LambdaQueryWrapper<ChatSession> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(ChatSession::getSessionId, dto.getSessionId());
        
        ChatSession session = baseMapper.selectOne(wrapper);
        if (session == null) {
            return false;
        }
        
        BeanUtils.copyProperties(dto, session);
        session.setUpdateTime(LocalDateTime.now());
        
        return baseMapper.updateById(session) > 0;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean deleteSession(String sessionId) {
        LambdaQueryWrapper<ChatSession> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(ChatSession::getSessionId, sessionId);
        
        return baseMapper.delete(wrapper) > 0;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateLastMessage(String sessionId, String message) {
        LambdaQueryWrapper<ChatSession> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(ChatSession::getSessionId, sessionId);
        
        ChatSession session = baseMapper.selectOne(wrapper);
        if (session == null) {
            return false;
        }
        
        session.setLastMessage(message);
        session.setLastMessageTime(LocalDateTime.now());
        session.setUpdateTime(LocalDateTime.now());
        
        return baseMapper.updateById(session) > 0;
    }
    
    /**
     * 将实体转换为VO
     */
    private ChatSessionVO convertToVo(ChatSession session) {
        ChatSessionVO vo = new ChatSessionVO();
        BeanUtils.copyProperties(session, vo);
        
        // 设置模型名称
        if (session.getModelId() != null) {
            ChatModel model = modelMapper.selectById(session.getModelId());
            if (model != null) {
                vo.setModelName(model.getName());
            }
        }
        
        return vo;
    }
    
    /**
     * 将实体列表转换为VO列表
     */
    private List<ChatSessionVO> convertToVoList(List<ChatSession> sessions) {
        if (sessions == null || sessions.isEmpty()) {
            return new ArrayList<>();
        }
        return sessions.stream()
                .map(this::convertToVo)
                .collect(Collectors.toList());
    }
} 